import { _decorator, Component, Node, Sprite, SpriteFrame, CircleCollider2D, Tween, tween, Vec3, Vec2, Color, RigidBody2D, Contact2DType, log } from 'cc';
import EventMgr from './EventManager';
import { EventType } from './enumType';
import { PathManager } from './PathManager';
import { MoveSpeed } from './BallChainManager';
const { ccclass, property } = _decorator;

// 小球颜色枚举（可根据资源扩展）
export enum BallColor {
    Red = 0,
    Green = 1,
    Blue = 2,
    GRAY = 3,
    Purple = 4,
    WHITE = 5,
}
export const BallColorMap = {
    [BallColor.Red]: Color.RED,
    [BallColor.Green]: Color.GREEN,
    [BallColor.Blue]: Color.BLUE,
    [BallColor.GRAY]: Color.GRAY,
    [BallColor.Purple]: Color.MAGENTA, 
    [BallColor.WHITE]: Color.WHITE, 
}

@ccclass('Ball')
export class Ball extends Component {
    @property(Sprite)sprite: Sprite = null!;
    @property Speed: number = 10;
    private collider: CircleCollider2D = null!;
    private rigidBody: RigidBody2D = null!;
    private targetIndex: number = -1;     // 当前目标路径点索引
    private ratio: number = 0; // 当前路径段插值比例（0~1）
    private segmentMoveSpeed: number = 0.3; // 每段路径移动速度（秒/段）
    public type: BallColor;
    private colliderOver: boolean = false; // 是否是发射的小球

    public get TargetIndex() {
        return this.targetIndex;
    }
    public set TargetIndex(index: number) {
        this.targetIndex = index;
    }
    public get Ratio() {
        return this.ratio; 
    }
    public set Ratio(ratio: number) {
        this.ratio = ratio;
    }

    public init(color: BallColor, spriteFrame?: SpriteFrame) {
        this.collider = this.getComponent(CircleCollider2D);
        this.rigidBody = this.getComponent(RigidBody2D);
        this.type = color;
        this.sprite.color = BallColorMap[color];
        spriteFrame && (this.sprite.spriteFrame = spriteFrame);
        this.collider.on(Contact2DType.BEGIN_CONTACT, this.onCollisionEnter, this);
    }

    protected update(dt: number): void {
        this.colliderOver && this.removeSelf();
    }

    private onCollisionEnter(selfCollider: CircleCollider2D, otherCollider: CircleCollider2D, contact: any) {
        if(this.targetIndex==-1&&!this.colliderOver){
            this.colliderOver = true;
            const otherBall = otherCollider.node.getComponent(Ball);
            EventMgr.Instance.emit(EventType.insert,this,otherBall);
            this.rigidBody.linearVelocity = Vec2.ZERO;
        }
        
    }
    
    // 播放爆炸动画（示例：隐藏精灵并销毁节点）
    public explode() {
        // 这里可替换为粒子系统或动画
        tween(this.node)
        .to(0.2, { scale: new Vec3(0, 0, 0) })
        .call(() => {
            this.node.destroy();
        })
        .start();
    }

    public async moveByUpDate(dt) {
        if (this.targetIndex >= PathManager.equidistantPoints.length - 1) return;
        
        // 计算当前路径段
        const startPoint = PathManager.equidistantPoints[this.targetIndex];
        const endPoint = PathManager.equidistantPoints[this.targetIndex + 1];
        
        // 更新插值比例
        this.ratio += dt / this.segmentMoveSpeed;
        
        // 到达下一路径点时重置状态
        if (this.ratio >= 1) {
            this.ratio = 0;
            this.targetIndex++;
            this.node.position = new Vec3(endPoint.x, endPoint.y, 0);
            return;
        }
    
        // 线性插值计算位置
        const newX = startPoint.x + (endPoint.x - startPoint.x) * this.ratio;
        const newY = startPoint.y + (endPoint.y - startPoint.y) * this.ratio;
        this.node.position = new Vec3(newX, newY, 0);
    }

    public moveByRatio(newRatio: number,targetIndex:number) {
        if (this.targetIndex >= PathManager.equidistantPoints.length - 1) return;

        // 计算当前路径段
        const startPoint = PathManager.equidistantPoints[this.targetIndex];
        const endPoint = PathManager.equidistantPoints[this.targetIndex + 1];

        // 线性插值计算位置
        const newX = startPoint.x + (endPoint.x - startPoint.x) * newRatio;
        const newY = startPoint.y + (endPoint.y - startPoint.y) * newRatio;
        this.node.position = new Vec3(newX, newY, 0);

        // 到达下一路径点时重置状态
        if (newRatio < this.ratio && this.targetIndex < targetIndex) {
            this.targetIndex++;
            this.node.position = new Vec3(endPoint.x, endPoint.y, 0); 
        }
        this.ratio = newRatio;
    }

    public shooter(dir:Vec2) {
        this.rigidBody.linearVelocity = dir.normalize().multiplyScalar(this.Speed);
    }

    public removeSelf() {
       if (this.node.position.x > 1000 || this.node.position.x < -1000 || this.node.position.y > 1000 || this.node.position.y < -1000) {
            this.node.destroy();
        } 
    }
}